package ae.pcfc.cldos.online.common.facade.provider;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;

import ae.pcfc.cldos.online.common.ConstantsCommon;
import ae.pcfc.cldos.online.common.ConstantsCommon.Steps;
import ae.pcfc.cldos.online.common.UltimusConstants;
import ae.pcfc.cldos.online.common.UltimusConstants.ApplicationResubmitDecision;
import ae.pcfc.cldos.online.common.UltimusConstants.EmployeeType;
import ae.pcfc.cldos.online.common.clddb.domain.AddressDetail;
import ae.pcfc.cldos.online.common.clddb.domain.AppMetaData;
import ae.pcfc.cldos.online.common.clddb.domain.ApplicationStatus;
import ae.pcfc.cldos.online.common.clddb.domain.EmployeeDetail;
import ae.pcfc.cldos.online.common.clddb.domain.PassportDetail;
import ae.pcfc.cldos.online.common.clddb.domain.PersonalDetail;
import ae.pcfc.cldos.online.common.clddb.domain.Process;
import ae.pcfc.cldos.online.common.clddb.domain.ReviewComments;
import ae.pcfc.cldos.online.common.clddb.domain.ServiceMaster;
import ae.pcfc.cldos.online.common.clddb.domain.TaskMaster;
import ae.pcfc.cldos.online.common.clddb.domain.TempFileStorage;
import ae.pcfc.cldos.online.common.clddb.domain.VisitVisa;
import ae.pcfc.cldos.online.common.clddb.domain.manager.AddressDetailDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.EmployeeDetailDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.PassportDetailDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.PersonalDetailDOM;
import ae.pcfc.cldos.online.common.clddb.domain.manager.VisitVisaDOM;
import ae.pcfc.cldos.online.common.etksdb.domain.Client;
import ae.pcfc.cldos.online.common.etksdb.domain.User;
import ae.pcfc.cldos.online.common.exception.BadAppException;
import ae.pcfc.cldos.online.common.exception.UltimusAppException;
import ae.pcfc.cldos.online.common.facade.BaseProcesesFacade;
import ae.pcfc.cldos.online.common.facade.VisitVisaFacade;
import ae.pcfc.cldos.online.common.factories.AppMetaDataFactory;
import ae.pcfc.cldos.online.common.tscdb.domain.TTscClientCompany;
import ae.pcfc.cldos.online.common.util.UtilCommon;
import ae.pcfc.cldos.online.common.vo.AppSaveResponseVO;
import ae.pcfc.cldos.online.common.vo.CommentsVO;
import ae.pcfc.cldos.online.common.vo.FileVO;
import ae.pcfc.cldos.online.common.vo.UserVO;
import ae.pcfc.cldos.online.common.vo.VisitVisaMainVO;
import ae.pcfc.cldos.online.common.vo.employee.details.AddressDetailsVO;
import ae.pcfc.cldos.online.common.vo.employee.details.EmployeeDetailsVO;
import ae.pcfc.cldos.online.common.vo.employee.details.PassportDetailsVO;
import ae.pcfc.cldos.online.common.vo.employee.details.PersonalDetailsVO;
import ae.pcfc.cldos.online.common.vo.employee.details.VisitVisaVO;
import ae.pcfc.cldos.online.common.vo.fnp.FNPPaymentAdviceVO;
import ae.pcfc.cldos.online.fnp.ConstantsFNP;
import ae.pcfc.cldos.online.gs.ConstantsGS;
import ae.pcfc.cldos.online.gs.service.client.GovtSysGS;
import ae.pcfc.cldos.online.gs.service.client.vo.GSFinancialDataVO;
import ae.pcfc.cldos.online.gs.service.client.vo.NotificationVO;
import ae.pcfc.cldos.online.wf.ConstantsWF;
import ae.pcfc.cldos.online.wf.service.client.vo.appdata.VisitVisaAppInfoVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.CompleteStepVO;
import ae.pcfc.cldos.online.wf.service.client.vo.base.LaunchIncedentVO;
import ae.pcfc.cldos.online.wf.service.client.vo.gvar.VisaResubmitGVarVO;
import ae.pcfc.cldos.online.wf.service.client.vo.gvar.VisaSubmitGVarVO;

/**
 * 
 * @author akhader
 *
 */
public class VisitVisaFacadeImpl extends BaseProcesesFacade implements VisitVisaFacade {

	private AddressDetailDOM addressDetailDOM;
	
	private VisitVisaDOM visitVisaDOM;
	
	private ae.pcfc.cldos.online.common.etksdb.domain.manager.ClientDOM clientDOM;
	private ae.pcfc.cldos.online.common.tscdb.domain.manager.TTscClientCompanyDOM tTscClientCompanyDOM;
	private GovtSysGS GovtSysGS;
	

	public ae.pcfc.cldos.online.common.tscdb.domain.manager.TTscClientCompanyDOM gettTscClientCompanyDOM() {
		return tTscClientCompanyDOM;
	}

	public void settTscClientCompanyDOM(
			ae.pcfc.cldos.online.common.tscdb.domain.manager.TTscClientCompanyDOM tTscClientCompanyDOM) {
		this.tTscClientCompanyDOM = tTscClientCompanyDOM;
	}

	public ae.pcfc.cldos.online.common.etksdb.domain.manager.ClientDOM getClientDOM() {
		return clientDOM;
	}

	public void setClientDOM(
			ae.pcfc.cldos.online.common.etksdb.domain.manager.ClientDOM clientDOM) {
		this.clientDOM = clientDOM;
	}

	public GovtSysGS getGovtSysGS() {
		return GovtSysGS;
	}

	public void setGovtSysGS(GovtSysGS govtSysGS) {
		GovtSysGS = govtSysGS;
	}

	public void setVisitVisaDOM(VisitVisaDOM visitVisaDOM) {
		this.visitVisaDOM = visitVisaDOM;
	}

	public void setAddressDetailDOM(AddressDetailDOM addressDetailDOM) {
		this.addressDetailDOM = addressDetailDOM;
	}
	
	private EmployeeDetailDOM employeeDetailDOM;
	
	public void setEmployeeDetailDOM(EmployeeDetailDOM employeeDetailDOM) {
		this.employeeDetailDOM = employeeDetailDOM;
	}
	
	private PersonalDetailDOM personalDetailDOM;
	
	public void setPersonalDetailDOM(PersonalDetailDOM personalDetailDOM) {
		this.personalDetailDOM = personalDetailDOM;
	}
	
	private PassportDetailDOM passportDetailDOM;
	
	public void setPassportDetailDOM(PassportDetailDOM passportDetailDOM) {
		this.passportDetailDOM = passportDetailDOM;
	}

	/**
	 * 
	 * @return reference number
	 */
	@Transactional(rollbackFor=Exception.class)
	public AppSaveResponseVO submit(VisitVisaMainVO visitVisaMainVO) throws Exception{
		return storeToDb(visitVisaMainVO, null, false);
	}
	
	/* (non-Javadoc)
	 * @see ae.pcfc.cldos.online.common.facade.VisitVisaFacade#reSubmit(ae.pcfc.cldos.online.common.vo.VisitVisaMainVO, java.lang.String)
	 */
	@Transactional(rollbackFor=Exception.class)
	public AppSaveResponseVO reSubmit(VisitVisaMainVO visitVisaMainVO, String appId) throws Exception{
		return storeToDb(visitVisaMainVO, appId, true);
	}
	/**
	 * @param clientId
	 * @return
	 */
	private String getCoLicNum(Long clientId){
		Client client = clientDOM.getClientById(clientId);
		TTscClientCompany tTscClientCompany = tTscClientCompanyDOM.getCompanyByTrakheesId(client.getCTrakheesId());
		return tTscClientCompany.getCcLicNo();
	}
	
	/**
	 * @param visitVisaMainVO
	 * @param appMetaData
	 * @param isResubmit
	 * @return
	 * @throws Exception
	 */
	private AppSaveResponseVO storeToDb(VisitVisaMainVO visitVisaMainVO, String appId, boolean isResubmit) throws Exception{
		AppSaveResponseVO appSaveResponseVO = new AppSaveResponseVO();
		Integer incident = null;
		
		UserVO userVO =  visitVisaMainVO.getUserVO();
		User user = userDomainObjectManager.findUserByUserName(userVO.getUsername());
		
		String coLicNo = getCoLicNum(user.getClientId());
		if(userVO.isAdmin()){
			buisnessValidationManager.validateOnlineVisitVisaData(coLicNo);
			buisnessValidationManager.validateEmployee(visitVisaMainVO.getPassportDetailsVO().getPpPsprtNameEng(), 
					visitVisaMainVO.getPassportDetailsVO().getPpPsprtNo(),true);
		}
		AppMetaDataFactory appMetaDataFactory = null;
		String clientRefNo = null;
		boolean backOfficeRejectflag=false;
		if(isResubmit){
			AppMetaData appMetaData = appMetaDataDOM.getAppMetaDataById(appId, Process.PROCESS_VISIT_VISA, Steps.RESUBMIT, user.getClientId());
			appMetaDataFactory = AppMetaDataFactory.createReSubmitFactory(appMetaData);
			if(appMetaData.getStatusCode()==5){
				backOfficeRejectflag=true;
			}
			if(userVO.isAdmin() && !backOfficeRejectflag){
				clientRefNo = gsInfoManager.getNextOfflineAppId(Process.PROCESS_VISIT_VISA);
				appMetaData.setClientRefNo(clientRefNo);
			}
		}else{
			if(userVO.isAdmin()){
				clientRefNo = gsInfoManager.getNextOfflineAppId(Process.PROCESS_VISIT_VISA);
			}
			appMetaDataFactory = AppMetaDataFactory.createSubmitFactory(clientRefNo);
		}
		
		AppMetaData appMetaData = appMetaDataFactory.getAppMetaData();
		
		Long serviceCode =  UtilCommon.convertStringToLong(visitVisaMainVO.getVisitVisaVO().getServiceCode());
		appMetaData.setServiceCode(serviceCode);
		
		if(userVO.isAdmin()){
			appMetaData.setStatusCode(ApplicationStatus.STATUS_APPROVED_BY_ONLINE_ADMIN);
		}else if (!isResubmit) {
			appMetaData.setStatusCode(ApplicationStatus.STATUS_INITIATED);
		} else {
			appMetaData.setStatusCode(ApplicationStatus.STATUS_RESUBMITED);
		}
		
		appMetaData.setProcessCode(Process.PROCESS_VISIT_VISA);
		appMetaData.setUserId(user.getUId());
		appMetaData.setClientId(user.getClientId());
		appMetaData.setApplicationDate(new Date());
		if(!isResubmit || appMetaData.getApplicationId()==null){
			appMetaDataDOM.add(appMetaData);
		}
		if(isResubmit){
			taskAndNotificationsManager.completeAllByAppId(appMetaData.getApplicationId());
		}
		
		if(!userVO.isAdmin()){	
			taskAndNotificationsManager.sendTask(appMetaData, TaskMaster.__ADMIN_APPROVE_TASK_CODE);
		}
		
		VisitVisa visitVisa = appMetaDataFactory.getVisitVisa();
		VisitVisaVO visitVisaVO = visitVisaMainVO.getVisitVisaVO();
		getMapper().map(visitVisaVO, visitVisa);
		visitVisa.setAppMetaData(appMetaData);
		visitVisaDOM.add(visitVisa);
		appMetaData.setVisitVisa(visitVisa);
		
		EmployeeDetail employeeDetail = appMetaDataFactory.getEmployeeDetails();
		EmployeeDetailsVO employeeDetailsVO = visitVisaMainVO.getEmployeeDetailsVO();
		getMapper().map(employeeDetailsVO, employeeDetail);
		employeeDetail.setAppMetaData(appMetaData);
		employeeDetailDOM.add(employeeDetail);
		appMetaData.setEmployeeDetail(employeeDetail);
		
		AddressDetail addressDetail = appMetaDataFactory.getAddressDetail();
		AddressDetailsVO addressDetailsVO = visitVisaMainVO.getAddressDetailsVO();
		getMapper().map(addressDetailsVO, addressDetail);
		addressDetail.setEmployeeDetail(employeeDetail);
		addressDetailDOM.add(addressDetail);
		employeeDetail.setAddressDetail(addressDetail);
		
		PersonalDetail personalDetail = appMetaDataFactory.getPersonalDetail();
		PersonalDetailsVO personalDetailsVO = visitVisaMainVO.getPersonalDetailsVO();
		getMapper().map(personalDetailsVO, personalDetail);
		personalDetail.setEmployeeDetail(employeeDetail);
		personalDetailDOM.add(personalDetail);
		employeeDetail.setPersonalDetail(personalDetail);
		
		PassportDetail passportDetail = appMetaDataFactory.getPassportDetail();
		PassportDetailsVO passportDetailsVO = visitVisaMainVO.getPassportDetailsVO();
		getMapper().map(passportDetailsVO, passportDetail);
		passportDetail.setEmployeeDetail(employeeDetail);
		passportDetailDOM.add(passportDetail);
		employeeDetail.setPassportDetail(passportDetail);
		
		String referenceNumber = appMetaData.getApplicationId().toString();
		if(!userVO.isAdmin()&& !backOfficeRejectflag){
			appMetaData.setClientRefNo(referenceNumber);
		}
		
		appMetaData.setTempFileStorages(fileStorageManager.storeFiles(appMetaData, visitVisaMainVO.getFileVOList(), 
				appMetaDataFactory.getTempFileStoragesMap()));
		
		
		//add list of param here
		if(userVO.isAdmin()){
			 String fnpServiceCode = visitVisaMainVO.getFnpServiceCode();
			 FNPPaymentAdviceVO fnpPaymentAdviceVO = 
					 fnpManager.generatePayment(appMetaData.getApplicationId(), userVO.getUsername(), fnpServiceCode, visitVisaMainVO.getFnpParams(),null,appMetaData.getClientRefNo());
			 appMetaData.setPaymentAdviceNo(fnpPaymentAdviceVO.getPaymentAdviceNumber());
			 appMetaData.getTempFileStorages().add(fnpPaymentAdviceVO.getStoredPaymentAdvice());
			//BG check
			GSFinancialDataVO gsFinancialDataVO = gsInfoManager.retriveFinancialData(coLicNo, user.getClientId());
			Double bg = gsFinancialDataVO.getBankGuaranteeBalance();
			if(bg < ConstantsGS.__BG_VISIT_VISA){
				//call fnp to deduct bg charges
				//add param list here
				FNPPaymentAdviceVO bgfnpPaymentAdviceVO  = 
						fnpManager.generatePayment(appMetaData.getApplicationId(), user.getUUsername(), 
								ConstantsFNP.FNP_VISIT_VISA_BG_SERVICE_CODE_ARAB_NATIONAL,null,null,appMetaData.getClientRefNo());
				appMetaData.setBgPaymentAdviceNo(bgfnpPaymentAdviceVO.getPaymentAdviceNumber());
				appMetaData.getTempFileStorages().add(bgfnpPaymentAdviceVO.getStoredPaymentAdvice());
				try{
					gsInfoManager.addVisitVisaBG(coLicNo, userVO.getUsername());
				}catch (Exception e) {
					e.printStackTrace();
					if(userVO.isAdmin()){
						fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), userVO.getUsername(), appMetaData.getPaymentAdviceNo(),appMetaData.getClientRefNo());
						if(appMetaData.getBgPaymentAdviceNo()!=null){
							fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), user.getUUsername(), 
									appMetaData.getBgPaymentAdviceNo(),appMetaData.getClientRefNo());
						}
					}
					throw new Exception(e);
				}
			}
		}
		
		VisitVisaAppInfoVO visitVisaAppInfoVO = new VisitVisaAppInfoVO();
		getMapper().map(visitVisaMainVO.getEmployeeDetailsVO(), visitVisaAppInfoVO);
		getMapper().map(visitVisaMainVO.getPassportDetailsVO(), visitVisaAppInfoVO);
		getMapper().map(visitVisaMainVO.getVisitVisaVO(), visitVisaAppInfoVO);
		
		/*add action comment*/
		ReviewComments reviewComments = new ReviewComments();
		reviewComments.setApplicationId(appMetaData.getApplicationId());
		reviewComments.setStatusCode(appMetaData.getStatusCode());
		reviewComments.setRcUserName(user.getUUsername());
		reviewComments.setRcComments(visitVisaMainVO.getCommentsVO().getComments());
		reviewCommentsDOM.add(reviewComments);
		
		/*Send notification*/
		//if(!userVO.isAdmin()){
			NotificationVO notificationVO = new NotificationVO();
			notificationVO.setOnlineAppId(appMetaData.getApplicationId().toString());
			Map<Object, Object> parameters = new HashMap<Object, Object>();
			parameters.put("comments", visitVisaMainVO.getCommentsVO().getComments());
			notificationVO.setParameters(parameters);
			taskAndNotificationsManager.sendNotification(appMetaData, notificationVO);
		//}
		
		//launch workflow
		if(appMetaData.getWfIncidentId() == null){
			if(userVO.isAdmin()){
				VisaSubmitGVarVO visaSubmitGVarVO = new VisaSubmitGVarVO();
				visaSubmitGVarVO.setG_ApplicationID(referenceNumber);
				visaSubmitGVarVO.setG_ApplicationSubmissionMedium(ConstantsCommon.APPLICATION_SUBMISSION_MEDIUM_ONLINE);
				visaSubmitGVarVO.setG_EPSubmissionMethod(appMetaData.getEmployeeDetail().getEdEpCollMethd());
				visaSubmitGVarVO.setG_ApplicationLaunchedBy(EmployeeType.COMPANY_ADMIN.getEmployeeType());
				try{		
					incident = genericVisaWF.launchIncident(appMetaData.getProcessCode(), new LaunchIncedentVO(), 
							visaSubmitGVarVO, visitVisaAppInfoVO);
				}catch (Exception e) {
					e.printStackTrace();
					fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), userVO.getUsername(), appMetaData.getPaymentAdviceNo(),appMetaData.getClientRefNo());
					if(appMetaData.getBgPaymentAdviceNo()!=null){
						fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), user.getUUsername(), 
									appMetaData.getBgPaymentAdviceNo(),appMetaData.getClientRefNo());
						gsInfoManager.removeVisitVisaBG(coLicNo, userVO.getUsername());
					}
					throw new UltimusAppException(e);
				}
				appMetaData.setWfIncidentId(incident.toString());
				appMetaData.setWfInitiatedBy(user.getUUsername());
			}
		} else{
			 incident = Integer.parseInt(appMetaData.getWfIncidentId());
			
			//:TODO put code for WF inwocation for resubmit
			VisaResubmitGVarVO visaResubmitGVarVO = new VisaResubmitGVarVO();
			visaResubmitGVarVO.setG_ApplicationID(referenceNumber);
			if(!userVO.isAdmin()){
				visaResubmitGVarVO.setG_ApplicationResubmittedBy(EmployeeType.EMPLOYEE.getEmployeeType());
			}else{
				visaResubmitGVarVO.setG_ApplicationResubmittedBy(EmployeeType.COMPANY_ADMIN.getEmployeeType());
			}
			visaResubmitGVarVO.setG_ApplicationResubmitDecision(ApplicationResubmitDecision.RESUBMITTED.getResubmitDecision());
			visaResubmitGVarVO.setG_EPSubmissionMethod(appMetaData.getEmployeeDetail().getEdEpCollMethd());
			
			CompleteStepVO completeStepVO = new CompleteStepVO();
			completeStepVO.setStrStepName(UltimusConstants.RESUBMIT_ONLINE_APPLICATION_STEP);
			completeStepVO.setStrUserName(ConstantsWF.ULTIMUS_ANONYMOUS_USER);
			completeStepVO.setnIncidentNumber(incident);
			
			try{		
				genericVisaWF.completeStep(appMetaData.getProcessCode(), completeStepVO, visaResubmitGVarVO, visitVisaAppInfoVO);
			}catch (Exception e) {
				e.printStackTrace();
				fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), userVO.getUsername(), appMetaData.getPaymentAdviceNo(),appMetaData.getClientRefNo());
				if(appMetaData.getBgPaymentAdviceNo()!=null){
					fnpManager.cancelPayment(appMetaData.getApplicationId().toString(), user.getUUsername(), 
								appMetaData.getBgPaymentAdviceNo(),appMetaData.getClientRefNo());
					gsInfoManager.removeVisitVisaBG(coLicNo, userVO.getUsername());
				}
				throw new UltimusAppException(e);
			}
		}
		
		/*
		 * transfer request to GS
		 */
			transferDataToGS(appMetaData, userVO, coLicNo);
		/*
		 * end of transfer
		 */
		
		if(isResubmit){
			appMetaDataDOM.update(appMetaData);
		} else {
			appMetaDataDOM.updateAndAddEtks(appMetaData);
		}
		appSaveResponseVO.setReferenceNo(appMetaData.getClientRefNo());
		appSaveResponseVO.setIncidentNo(appMetaData.getWfIncidentId());
		
		return appSaveResponseVO;
	}
	/**
	 * @param applicationId
	 * @param userVO
	 * @param step
	 * @return
	 * @throws BadAppException
	 */
	@Transactional
	public VisitVisaMainVO getVisitVisaViewDtls(String applicationId, UserVO userVO, Steps step) throws BadAppException{
		VisitVisaMainVO visitVisaVO = new VisitVisaMainVO();
		visitVisaVO = getVisitVisaDetailByAppId(applicationId, userVO, step);
		visitVisaVO.setWfStatus(gsInfoManager.getWfStatus(visitVisaVO.getClientReferenceNo()));
		return visitVisaVO;
	}
	
	
	@Transactional
	public VisitVisaMainVO getVisitVisaDetailByAppId(String applicationId, UserVO userVO, Steps step) throws BadAppException{
		AppMetaData appMetaData = null;
		
		if(userVO.isGeneralAdmin()){
			appMetaData = appMetaDataDOM.getAppMetaDataByIdForGeneralAdmin(applicationId, Process.PROCESS_VISIT_VISA, step);
		} else {
			User user = userDomainObjectManager.findUserByUserName(userVO.getUsername());
			appMetaData = appMetaDataDOM
					.getAppMetaDataById(applicationId, Process.PROCESS_VISIT_VISA, step, user.getClientId());
		}
		
		VisitVisaMainVO visitVisaMainVO = new VisitVisaMainVO();
		
		visitVisaMainVO.setClientReferenceNo(appMetaData.getClientRefNo());
		visitVisaMainVO.setInitiatedBy(appMetaData.getWfInitiatedBy());
		
		EmployeeDetail employeeDetail = appMetaData.getEmployeeDetail();
		EmployeeDetailsVO employeeDetailsVO = new EmployeeDetailsVO();
		getMapper().map(employeeDetail, employeeDetailsVO);
		visitVisaMainVO.setEmployeeDetailsVO(employeeDetailsVO);
		
		
		AddressDetailsVO addressDetailsVO = new AddressDetailsVO();
		AddressDetail addressDetail = employeeDetail.getAddressDetail();
		getMapper().map(addressDetail, addressDetailsVO);
		visitVisaMainVO.setAddressDetailsVO(addressDetailsVO);
		
		CommentsVO commentsVO = new CommentsVO();
		commentsVO.setComments(appMetaData.getAppComments());
		visitVisaMainVO.setCommentsVO(commentsVO);
		
		
		List<TempFileStorage> tempFileStoragesList = appMetaData.getTempFileStorages();
		List<FileVO> fileVOList = new ArrayList<FileVO>(tempFileStoragesList.size());
		for(TempFileStorage tempFileStorage : tempFileStoragesList){
			FileVO fileVO = new FileVO();
			getMapper().map(tempFileStorage, fileVO);
			fileVOList.add(fileVO);
		}
		visitVisaMainVO.setFileVOList(fileVOList);
		
		PassportDetail passportDetail = employeeDetail.getPassportDetail();
		PassportDetailsVO passportDetailsVO = new PassportDetailsVO();
		getMapper().map(passportDetail, passportDetailsVO);
		visitVisaMainVO.setPassportDetailsVO(passportDetailsVO);
		
		PersonalDetail personalDetail = employeeDetail.getPersonalDetail();
		PersonalDetailsVO personalDetailsVO = new PersonalDetailsVO();
		getMapper().map(personalDetail, personalDetailsVO);
		visitVisaMainVO.setPersonalDetailsVO(personalDetailsVO);
		
		VisitVisa visitVisa = appMetaData.getVisitVisa();
		VisitVisaVO visitVisaVO = new VisitVisaVO();
		getMapper().map(visitVisa, visitVisaVO);
		visitVisaMainVO.setVisitVisaVO(visitVisaVO);
		
		visitVisaMainVO.setApplicationCommentVOs(getCommentsVOList(appMetaData.getReviewComments()));
		
		return visitVisaMainVO;
	}
	
}
